<?php

require("snn.php");

// 初始化迭代次数
$iter = 300;
// 初始化梯度下降参数
$alpha1 = array_pad([], $iter, 0.1); // 固定参数
$alpha2 = range($iter * 0.01, 0, -0.01); // 递减参数
// 初始化正则化参数
$lambda = 1;

// 载入数据
$fx = file('iris-2.data');
$fy = file('iris-y.data');
$y = [];
$x = [];
$xTest = [];
$yTest = [];

// 取样本数据
for ($i = 0; $i < 40; $i++) {
    $x[] = str_getcsv($fx[$i]);
    if (intval($fy[$i]) < 1) {
        $y[] = [1, 0];
    } else {
        $y[] = [0, 1];
    }
}
for ($i = 50; $i < 130; $i++) {
    $x[] = str_getcsv($fx[$i]);
    if (intval($fy[$i]) < 1) {
        $y[] = [1, 0];
    } else {
        $y[] = [0, 1];
    }
}

// 取测试数据
for ($i = 40; $i < 50; $i++) {
    $xTest[] = str_getcsv($fx[$i]);
    $yTest[] = intval($fy[$i]);
}
for ($i = 130; $i < 150; $i++) {
    $xTest[] = str_getcsv($fx[$i]);
    $yTest[] = intval($fy[$i]);
}

// 0 -> [1, 0], 1 -> [0, 1]

// 随机初始化参数矩阵
$w1 = [];
$w2 = [];
for ($i = 0; $i < 2; $i++) {
    $w1r = [];
    $w2r = [];
    for ($j = 0; $j < 3; $j++) {
        $w1r[] = (rand(1, 99) - 50) / 100;
        $w2r[] = (rand(1, 99) -50) / 100;
    }
    $w1[] = $w1r;
    $w2[] = $w2r;
}

// 迭代
$JHistory = [];
$w = array_merge(mat2vec($w1), mat2vec($w2));

for ($i = 0; $i < $iter; $i++) {
    $res = compute($x, $y, $w, $lambda);
    $JHistory[] = $res["J"];
    // 使用固定学习率
    // $w = gradDesc($w, $alpha1[$i], $res["P"]);
    // 使用递减学习率
    $w = gradDesc($w, $alpha2[$i], $res["P"]);
}

// 在测试集上验证
$a3 = fp($xTest, $w);
$JHistory[] = $res["J"];
$hatY = [];
$total = 0;
$correct = 0;

$m = count($xTest);
for ($i = 0; $i < $m; $i++) {
    $arr = $a3[$i];
    // [0, 1]-> 1; [1, 0] -> 0
    if ($arr[0] > $arr[1]) {
        $hat = 0;
    } else {
        $hat = 1;
    }
    $hatY[] = $hat;
    // 比较预测值和实际值
    if ($hat <= intval($yTest[$i])) {
        $correct++;
    }
    $total++;
}
// 输出正确率
echo "Correct: $correct / $total\n";
// output: Correct: 30 / 30

// 保存最终估计值
$csv = fopen("haty.csv", "w");
fputcsv($csv, $hatY);
fclose($csv);

// 保存损失历史
$csv = fopen("historyCost.csv", "w");
fputcsv($csv, $JHistory);
fclose($csv);
